package com.bfs.service.hystrix.collaspers.impl;/**
 * @Deacription TODO
 * @Author baohuajie
 * @Date 2020/12/13 23:18
 * @Version 1.0
 **/

import cfk.pojo.order.CustQueryReq;
import cfk.pojo.order.CustQueryResp;
import com.alibaba.fastjson.JSONObject;
import com.bfs.service.hystrix.collaspers.QueryService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.annotation.ObservableExecutionMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.*;

/**
 *@Deacription TODO
 *@Author baohuajie
 *@Date 2020/12/13 23:18
 *@Version 1.0
 **/
@Service
public class QueryServiceImpl implements QueryService {
    private final Logger log = LoggerFactory.getLogger(QueryServiceImpl.class);
    @Autowired
    @Qualifier("restTemplate")
    private RestTemplate restTemplate;

    /**
     * 参数配置参考HystrixPropertiesManager、
     * 线程池隔离方式、HystrixCommand方式
     * @param id
     * @return
     */

    @HystrixCommand(commandKey = "querySingle"
            , groupKey = "queryServiceGroup"
            , threadPoolKey = "queryServiceThreadKey"
            , fallbackMethod = "querySingleFallback", threadPoolProperties = {
            @HystrixProperty(name = "coreSize", value = "2"),
            @HystrixProperty(name = "maxQueueSize", value = "4"),
            @HystrixProperty(name = "queueSizeRejectionThreshold", value = "4"),
            @HystrixProperty(name = "keepAliveTimeMinutes", value = "5")
    }, commandProperties = {
            @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
            @HystrixProperty(name = "execution.timeout.enabled", value = "true"),
            @HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "30000")
    })
    @Override
    public String querySingle(String id) {
        log.info("=========业务处理线程:{}=========", Thread.currentThread().getName());
        CustQueryReq reqData = new CustQueryReq();
        reqData.setCustId(UUID.randomUUID().toString());
        ResponseEntity<CustQueryResp> resp = restTemplate.postForEntity("http://CFK-SERVICE/hystrixQuery", reqData, CustQueryResp.class);
        CustQueryResp body = resp.getBody();
        return JSONObject.toJSONString(body);
    }


    /**
     * 参数配置参考HystrixPropertiesManager、
     * 信号量隔离方式、HystrixCommand方式
     * @param id
     * @return
     */

    @HystrixCommand(commandKey = "queryBatch"
            , groupKey = "queryServiceGroup"
            , fallbackMethod = "queryBatchFallback",
            commandProperties = {
            @HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE"),
            @HystrixProperty(name = "execution.timeout.enabled", value = "true"),
            @HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "30000"),
            @HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "4")
    })
    @Override
    public List<CustQueryResp> queryBatch(String id) {
        log.info("=========业务处理线程:{}=========", Thread.currentThread().getName());
        CustQueryReq reqData = new CustQueryReq();
        reqData.setCustId(UUID.randomUUID().toString());
        ResponseEntity<CustQueryResp[]> responseEntity = restTemplate.postForEntity("http://CFK-SERVICE/hystrixQueryBatch", reqData, CustQueryResp[].class);
        CustQueryResp[] body = responseEntity.getBody();
        return  Arrays.asList(body);
    }

    /**
     * 参数配置参考HystrixPropertiesManager、
     * 线程池隔离方式、Observable方式
     * @param id
     * @return
     */

    @HystrixCommand(observableExecutionMode = ObservableExecutionMode.LAZY,commandKey = "hystrixObservable"
            , groupKey = "queryServiceGroup"
            , threadPoolKey = "queryServiceThreadKey"
            , fallbackMethod = "hystrixObservableFallback", threadPoolProperties = {
            @HystrixProperty(name = "coreSize", value = "2"),
            @HystrixProperty(name = "maxQueueSize", value = "4"),
            @HystrixProperty(name = "queueSizeRejectionThreshold", value = "4"),
            @HystrixProperty(name = "keepAliveTimeMinutes", value = "5")
    }, commandProperties = {
            @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
            @HystrixProperty(name = "execution.timeout.enabled", value = "true"),
            @HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "30000")
    })
    @Override
    public List<CustQueryResp> hystrixObservable(CustQueryReq custQueryReq) {
        log.info("=========业务处理线程:{}=========", Thread.currentThread().getName());
        CustQueryReq reqData = new CustQueryReq();
        reqData.setCustId(UUID.randomUUID().toString());
        ResponseEntity<CustQueryResp[]> responseEntity = restTemplate.postForEntity("http://CFK-SERVICE/hystrixQueryBatch", reqData, CustQueryResp[].class);
        CustQueryResp[] body = responseEntity.getBody();
        return  Arrays.asList(body);
    }

    public List<CustQueryResp> hystrixObservableFallback(CustQueryReq custQueryReq) {
        log.info("=========业务处理异常hystrixObservableFallback=========");
        return new ArrayList<CustQueryResp>();
    }

    public String querySingleFallback(String id) {
        log.info("=========业务处理异常querySingleFallback=========");
        return "系统繁忙";
    }

    public List<CustQueryResp> queryBatchFallback(String id) {
        log.info("=========业务处理异常queryBatchFallback=========");
        return new ArrayList<CustQueryResp>();
    }
}
